package space.xiaoyuan.middleware.db.router.config;

import org.apache.ibatis.plugin.Interceptor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import space.xiaoyuan.middleware.db.router.DBRouterConfig;
import space.xiaoyuan.middleware.db.router.DBRouterConfigDetail;
import space.xiaoyuan.middleware.db.router.DBRouterJoinPoint;
import space.xiaoyuan.middleware.db.router.dynamic.DynamicDataSource;
import space.xiaoyuan.middleware.db.router.dynamic.DynamicMybatisPlugin;
import space.xiaoyuan.middleware.db.router.strategy.IDBRouterStrategy;
import space.xiaoyuan.middleware.db.router.strategy.impl.DBRouterStrategyHashCode;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
@ComponentScan(basePackages = "space.xiaoyuan.middleware.db.router")
public class DataSourceAutoConfig{
    @Resource
    private DBRouterConfig dbRouterConfig;
    /**
     * 默认数据源配置
     */
    @Bean()
    public IDBRouterStrategy routerStrategy(){
        return new DBRouterStrategyHashCode(dbRouterConfig);
    }
    @Bean("db-router-point")
    @ConditionalOnMissingBean
    public DBRouterJoinPoint joinPoint(IDBRouterStrategy routerStrategy){
        return new DBRouterJoinPoint(dbRouterConfig,routerStrategy);
    }

    @Bean()
    public Interceptor mybatisPlugin(){
        return new DynamicMybatisPlugin();
    }

    @Bean()
    public DataSource dataSource(){
        Map<Object,Object> targetDataSources = new HashMap<>();
        dbRouterConfig.getDatasourceMap().forEach((key,value)->{
            targetDataSources.put(key,new DriverManagerDataSource(
                    value.getUrl(),
                    value.getUsername(),
                    value.getPassword()
                    ));
        });

        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dbRouterConfig.getDatasourceMap().get(dbRouterConfig.getDefaultDatasource());

        DBRouterConfigDetail dbRouterConfigDetail = dbRouterConfig.getDatasourceMap().get(dbRouterConfig.getDefaultDatasource());
        dynamicDataSource.setDefaultTargetDataSource(new DriverManagerDataSource(
                dbRouterConfigDetail.getUrl(),
                dbRouterConfigDetail.getUsername(),
                dbRouterConfigDetail.getPassword())
        );

        return dynamicDataSource;
    }

    /**
     * 事务管理器
     */
    @Bean
    public TransactionTemplate transactionTemplate(DataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);

        TransactionTemplate transactionTemplate = new TransactionTemplate();
        //设置事务传播级别
        transactionTemplate.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
        //设置事务管理器
        transactionTemplate.setTransactionManager(dataSourceTransactionManager);
        return transactionTemplate;
    }
    //@Bean
    public PlatformTransactionManager platformTransactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

}

